L.RoomModerator = L.Class.extend({
	includes: L.Mixin.Events,

	initialize: function(room, couplingOptions) {
		this._room = room;
		this._room.on('roomListSet', this._handleRoomListSet, this);
		
		this._editors = [ Number(this._room.getOwnerId()) ];
		this._activeUsers = [];
		
		if ( couplingOptions != null && couplingOptions.enabled )
	    	this._couple(couplingOptions);
		
		var roomList = this._room.getRoomList();
//		console.log("roomList");
//		console.log(roomList);
		if ( roomList ) {
			var group = this._room.getRoomList().getGroup();
			for ( var k = 0; group != null && k < group.getMembers().length; ++k )
				this.addEditor(Number(group.getMembers()[k]));
			
			this._handleRoomListSet(roomList);
		}
	},
	
	_handleRoomListSet: function(roomList) {
//		console.log("_handleRoomListSet: function(roomList) {");
		var group = roomList.getGroup();
//		console.log("group");
//		console.log(group);
		if ( group != null )
			group.on('memberEvent', this._handleGroupMemberEvent, this);
	},
	
	_handleGroupMemberEvent: function( params ) {
//		console.log("_handleGroupMemberEvent: function( params ) {");
//		console.log("params.action");
//		console.log(params.action);
		if ( params.action == 'addMember' )
			this.addEditor(Number(params.userId));
	},
	
	userJoin: function(userId) {
		if ( $.inArray(userId, this._activeUsers) < 0 ) {
			this._activeUsers.push(Number(userId));
			this.fire('userEvent',
				{ 
					action: 'userJoin',
					userId: userId,
					moderator: this
				}
			);
			var roomList = this._room.getRoomList();
//			console.log(roomList);
			if ( roomList != null ) {
				var group = roomList._group;
				if ( group != null && group.isMember(userId) && $.inArray(Number(userId), this._editors) < 0 )
					this._addEditor(userId);
			}
		}
	},
	
	userLeave: function(userId) {
		if ( $.inArray(Number(userId), this._activeUsers) >= 0 ) {
			this._activeUsers.splice(this._activeUsers.indexOf(Number(userId)), 1);
			this.fire('userEvent',
				{ 
					action: 'userLeave',
					userId: userId,
					moderator: this
				}
			);
		}
	},
	
	_addEditor: function(userId) {
		this._editors.push(Number(userId));
		this.fire('userEvent',
			{ 
				action: 'addEditor',
				userId: userId,
				moderator: this
			}
		);
	},
	
	addEditor: function(userId) {
		if ( $.inArray(Number(userId), this._editors) < 0 ) {
			this._addEditor(userId);
		}
	},
	
	removeEditor: function(userId) {
		if ( $.inArray(Number(userId), this._editors) >= 0 ) {
			console.log("this._editors.splice(this._editors.indexOf(userId), 1);");
			this._editors.splice(this._editors.indexOf(Number(userId)), 1);
			this.fire('userEvent',
				{ 
					action: 'removeEditor',
					userId: userId,
					moderator: this
				}
			);
		}
	},
	
	requestEditorAddition: function(requesterId, newEditorId) {
		if ( Number(this._room.getOwnerId()) == Number(requesterId) ) {
			this.addEditor(Number(newEditorId));
			return true;
		} else if ( this._room.getType() == "groupal" && $.inArray(Number(requesterId), this._editors) ) {
			this.addEditor(Number(newEditorId));
			return true;
		}
		return false;
	},
	
	requestEditorRemoval: function(requesterId, editorId) {
		if ( Number(this._room.getOwnerId()) == Number(requesterId) ) {
			this.removeEditor(Number(editorId));
			return true;
		}
		return false;
	},
	
	getCurrentlyEditing: function() {
		res = [];
		
		for ( var i = 0; i < this._editors.length; ++i ) {
			var editor = this._editors[i];
			if ( $.inArray(editor, this._activeUsers) >= 0 )
				res.push(Number(editor));
		}			
		
		return res;
	},
	
	canEdit: function(userId) {
		var user = Skt.user_list.getUser(userId);
		return (user != null && user.rol != 'tv') && (Number(this._room.getOwnerId()) == Number(userId) || ($.inArray(Number(userId), this._editors) >= 0));
	},
	
	getRoom: function() {
		return this._room;
	},
	
	getEditors: function() {
		return this._editors;
	},
	
	getActiveUsers: function() {
		return this._activeUsers;
	},
	getState:function(){
		return {
			activeUsers:this.getActiveUsers(),
			editors:this.getEditors()
			};
	},
	setState:function(state){
		var newUserIds={};
		var newEditorsIds={};
		var users=[];
		var idsToDelete=[];
		var editors=[];
	
		//get new user list
		for(var i=0;i<state.activeUsers.length;i=i+1){
			newUserIds[state.activeUsers[i]]=true;
		}
		//remove disconected users
		users=this.getActiveUsers();
		for(var i=0;i<users.length;i=i+1){
			if(!newUserIds[users[i]]){
				idsToDelete.push(users[i]);
			}
		}
		for(var i=0;i<idsToDelete.length;i=i+1){
			this.userLeave(idsToDelete[i]);
		}
		//add  new users
		for(var i=0;i<state.activeUsers.length;i=i+1){
			this.userJoin(state.activeUsers[i]);
		}
	
		//new editors
		for(var i=0;i<state.editors.length;i=i+1){
			this.addEditor(state.editors[i]);
			newEditorsIds[state.editors[i]]=true;
		}
		//remove editors
		editors=this.getEditors();
		idsToDelete=[];
		for(var i=0;i<editors.length;i=i+1){
			if(!newEditorsIds[editors[i]]){
				idsToDelete.push(editors[i]);
			}
		}
		for(var i=0;i<idsToDelete.length;i=i+1){
			this.removeEditor(idsToDelete[i]);
		}
	},

	_couple: function(couplingOptions) {
		couplingOptions.adapter.coupleObject( 
			couplingOptions.carriedId + "-" + this._room.getId() + "-moderator", 
			this, 
			{
				explicitMapping:[ "userJoin", "userLeave", "addEditor", "removeEditor"],
				messageType:"STATE"
			}
		);
	}

});